#include "StdAfx.h"
#include "MyImage.h"


using namespace std;
MyImage::MyImage(string fileName)throw(IllegalArgumentException)
{
	if(fileName.empty()){
		throw IllegalArgumentException("MyImage Class, file name is empty");
	}

	if(fileName==""){
		throw IllegalArgumentException("MyImage Class, file name is empty");
	}
	
	string fileType;
	int i = fileName.size()-1;

	while (fileName.at(i)!='.'){
		if (i<=0){
			throw IllegalArgumentException("MyImage Class, unknown file type");
		}
		i--;
	}

	fileType = fileName.substr(i+1,fileName.size()-i);
	_fileName = fileName;

	if(fileType=="bmp"){
		bitMapLoader(_fileName);
	}
}

MyImage::MyImage( BitMap bitmap )
{
	_bitmap = new BitMap(bitmap.getBitmapFileHeader(),bitmap.getBitmapInfoHeader(),bitmap.getPalette(),bitmap.getImageData());
}


MyImage::~MyImage(void)
{
	delete _bitmap;
}

void MyImage::bitMapLoader( std::string fileName )
{
	FILE *fp;
	fp = fopen(fileName.c_str(),"rb");
		if(fp==NULL){
			throw FileException("MyImage Class, File not exist"); 
		}

	fseek(fp,0L,SEEK_END);
		
	unsigned int fSize=ftell(fp);
	rewind(fp);
		if(fSize < sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)){
			throw FileException("MyImage Class, Incorrect file type"); 
		}

	BITMAPFILEHEADER bmpHeader;
	BITMAPINFOHEADER bmpInfo;
	vector <RGBQUAD> rgbQuad;
	vector<unsigned char> imageData;

	int ret = fread(&bmpHeader,sizeof(bmpHeader),1,fp);
	if(bmpHeader.bfType != 0x4D42) {
		fclose(fp);
		throw FileException("MyImage Class,Incorrect bmp file type"); 
	}
	if(bmpHeader.bfOffBits == 0) { 
		fclose(fp);
		throw FileException("MyImage Class,Incorrect bmp file header"); 
	}

	ret=fread(&bmpInfo,sizeof(bmpInfo),1,fp);

	if(bmpInfo.biClrUsed!=0){
		rgbQuad.resize(bmpInfo.biClrUsed);
		ret=fread(&rgbQuad.at(0),bmpInfo.biClrUsed*sizeof(RGBQUAD),1,fp);
	}

	fseek(fp, bmpHeader.bfOffBits, SEEK_SET);
	imageData.resize(bmpInfo.biSizeImage,0);
	fread(&imageData.at(0),imageData.size()*sizeof(unsigned char),1,fp);
	
	// if bmpInfo.biCompression == BI_RGB then no need decompression

	if (bmpInfo.biCompression == BI_RLE8){
		// load rle8 decompression
	}
	if (bmpInfo.biCompression == BI_RLE4){
		//load rle4 decompression
	}
	if (bmpInfo.biCompression == BI_BITFIELDS){
		// load uncompressed rgb. This is valid when used with 16- and 32-bpp bitmaps.
	}
	if (bmpInfo.biCompression == BI_JPEG){
		//load as jpeg decompression
	}
	if (bmpInfo.biCompression == BI_PNG){
		//load as png decompression
	}
	fclose(fp);

	_bitmap = new BitMap(bmpHeader,bmpInfo,rgbQuad,imageData);

}

BitMap MyImage::getImageBitMapSample( unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
{
	return _bitmap->getBimapArea(x1,y1,x2,y2);
}

void MyImage::getImageResolution(unsigned int *x, unsigned int *y )
{

	*x = _bitmap->getBitmapInfoHeader().biWidth;
	*y = _bitmap->getBitmapInfoHeader().biHeight;
}

void MyImage::saveImage( string fileName, string type )
{
	FILE *fp;
	string fName = fileName+"."+type;

	fp = fopen(fName.c_str(),"wb");

	fwrite(&_bitmap->getBitmapFileHeader(),sizeof(BITMAPFILEHEADER),1,fp);
	fwrite(&_bitmap->getBitmapInfoHeader(),sizeof(BITMAPINFOHEADER),1,fp);
	
	int clUsed = _bitmap->getBitmapInfoHeader().biClrUsed;
	if(clUsed!=0){
		fwrite(&_bitmap->getPalette().at(0),_bitmap->getPalette().size()*sizeof(RGBQUAD),1,fp);
	}

	fwrite(&_bitmap->getImageData().at(0),_bitmap->getImageData().size()*sizeof(unsigned char),1,fp);
	
	fclose(fp);
}

std::vector<float> MyImage::extractImageData()
{
	vector<unsigned char> charData = _bitmap->getImageData();
	vector<float> floatData;
	floatData.resize(charData.size());
	for (int i=0; i< charData.size(); i++){
		floatData[i] = static_cast<float>(charData[i]);
	}
	return floatData;
}
